import CMap from './CMap'

/**
 * 计时器管理
 */
export default class Timer {
    static map: CMap = new CMap()

    static delay(millisecond?: number) {
        return new Promise<void>((resolve) => {
            Timer.once(() => resolve(), millisecond ?? 0)
        })
    }

    /**
     * 执行列表
     */
    static run = (...run: { run: () => void; time?: number }[]) => {
        run.forEach((el) => {
            let time = el.time ?? 0
            Timer.once(() => {
                if (el.run) el.run()
            }, time)
        })
    }

    /**
     * 异步执行列表,执行完所有任务会调用回调
     */
    static runAsync = async (
        run: {
            run: () => void
            time?: number | undefined
        }[],
        callback?: any
    ) => {
        await run.reduce((prev, cur) => {
            return Promise.resolve().then(() => {
                return Timer.onceAsync(cur.run, cur.time ?? 0)
            })
        }, {})
        if (callback) callback()
    }

    /**
        循环执行
     */
    static on = (callback: Function, time: number, runOne: boolean = false): string => {
        let timer = setInterval(callback, time)
        this.map.set('i' + timer, timer)
        if (runOne) callback()
        return 'i' + timer
    }

    /**
     * 执行一次
     */
    static once = (callback: Function, time: number): string => {
        let timer = setTimeout(callback, time)
        this.map.set('t' + timer, timer)
        return 't' + timer
    }

    /**
     * 异步执行一次
     */
    static onceAsync = (callback: Function, time: number): Promise<void> => {
        return new Promise<void>((resolve, reject) => {
            setTimeout(() => {
                callback()
                resolve()
            }, time)
        })
    }

    /**
        注销循环
     */
    static un(...name: any) {
        for (let i = 0; i < name.length; i++) {
            clearInterval(this.map.get(name[i]))
            this.map.remove(name[i])
        }
    }

    /**
        注销一次
     */
    static unOnce(...name: any) {
        for (let i = 0; i < name.length; i++) {
            clearTimeout(this.map.get(name[i]))
            this.map.remove(name[i])
        }
    }

    /**
        注销所有循环
     */
    static unAll() {
        this.map.forEach((key: any, value: any) => {
            // console.log(key, value);
            if (key.indexOf('i') != -1) clearTimeout(value)
            else clearInterval(value)
        })
        this.map.clear()
    }
}
